package com.ximi.ximimall.goods.controller;

import cn.hutool.core.collection.CollectionUtil;
import javax.validation.constraints.NotNull;
import com.ximi.ximimall.common.component.LocalCache;
import com.ximi.ximimall.common.util.ResponseUtil;
import com.ximi.ximimall.goods.service.*;
import com.ximi.ximimall.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.concurrent.*;

/**
 * @author 西米的风
 * @description TODO
 * @date 2022-10-23 8:45
 */
@RestController
@RequestMapping("/wx/goods")
public class GoodsController {

    @Autowired
    private LitemallGoodsService goodsService;

    @Autowired
    private LitemallBrandService brandService;

    @Autowired
    private LitemallGoodsProductService productService;

    @Autowired
    private LitemallIssueService goodsIssueService;

    @Autowired
    private LitemallGoodsAttributeService goodsAttributeService;

    @Autowired
    private LitemallGoodsSpecificationService goodsSpecificationService;



    @Autowired
    private LocalCache localCache;

    private static String NEW_GOODS_KEY = "new_goods_key";

    private static String HOT_GOODS_KEY = "hot_goods_key";

    private final static ArrayBlockingQueue<Runnable> WORK_QUEUE = new ArrayBlockingQueue<>(9);

    private final static RejectedExecutionHandler HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();
    private static ThreadPoolExecutor executorService = new ThreadPoolExecutor(16, 16, 1000, TimeUnit.MILLISECONDS, WORK_QUEUE, HANDLER);


    @RequestMapping("/queryByNew")
    public Object queryByNew() {
        List<LitemallGoods> list  = (List<LitemallGoods>) localCache.get(NEW_GOODS_KEY);
        if(CollectionUtil.isNotEmpty(list)){
            return ResponseUtil.ok(list);
        }
        list  = goodsService.queryByNew(0,6);
        localCache.setLocalCache(NEW_GOODS_KEY,list);
        return ResponseUtil.ok(list);
    }


    @RequestMapping("/queryByHot")
    public Object queryByHot() {
        List<LitemallGoods> list  = (List<LitemallGoods>) localCache.get(HOT_GOODS_KEY);
        if(CollectionUtil.isNotEmpty(list)){
            return ResponseUtil.ok(list);
        }
        list  = goodsService.queryByHot(0,6);
        localCache.setLocalCache(HOT_GOODS_KEY,list);
        return ResponseUtil.ok(list);
    }

    /**
     * 在售的商品总数
     *
     * @return 在售的商品总数
     */
    @RequestMapping("/count")
    public Object count() {
        Integer goodsCount = goodsService.queryOnSale();
        return ResponseUtil.ok(goodsCount);
    }

    /**
     * 商品详情
     * <p>
     * 用户可以不登录。
     * 如果用户登录，则记录用户足迹以及返回用户收藏信息。
     *
     * @param userId 用户ID
     * @param id     商品ID
     * @return 商品详情
     */
    @RequestMapping("/detail")
    public Object detail( Integer userId, @NotNull Integer id) {
        // 商品信息
        LitemallGoods info = goodsService.findById(id);

        // 商品属性
        Callable<List> goodsAttributeListCallable = () -> goodsAttributeService.queryByGid(id);

        // 商品规格 返回的是定制的GoodsSpecificationVo
        Callable<Object> objectCallable = () -> goodsSpecificationService.getSpecificationVoList(id);

        // 商品规格对应的数量和价格
        Callable<List> productListCallable = () -> productService.queryByGid(id);

        // 商品问题，这里是一些通用问题
        Callable<List> issueCallable = () -> goodsIssueService.querySelective("", 1, 4, "", "");

        // 商品品牌商
        Callable<LitemallBrand> brandCallable = ()->{
            Integer brandId = info.getBrandId();
            LitemallBrand brand;
            if (brandId == 0) {
                brand = new LitemallBrand();
            } else {
                brand = brandService.findById(info.getBrandId());
            }
            return brand;
        };

        // 评论
//        Callable<Map> commentsCallable = () -> {
//            List<LitemallComment> comments = commentService.queryGoodsByGid(id, 0, 2);
//            List<Map<String, Object>> commentsVo = new ArrayList<>(comments.size());
//            long commentCount = PageInfo.of(comments).getTotal();
//            for (LitemallComment comment : comments) {
//                Map<String, Object> c = new HashMap<>();
//                c.put("id", comment.getId());
//                c.put("addTime", comment.getAddTime());
//                c.put("content", comment.getContent());
//                c.put("adminContent", comment.getAdminContent());
//                LitemallUser user = userService.findById(comment.getUserId());
//                c.put("nickname", user == null ? "" : user.getNickname());
//                c.put("avatar", user == null ? "" : user.getAvatar());
//                c.put("picList", comment.getPicUrls());
//                commentsVo.add(c);
//            }
//            Map<String, Object> commentList = new HashMap<>();
//            commentList.put("count", commentCount);
//            commentList.put("data", commentsVo);
//            return commentList;
//        };

        //团购信息
//        Callable<List> grouponRulesCallable = () ->rulesService.queryByGoodsId(id);

        // 用户收藏
        int userHasCollect = 0;
//        if (userId != null) {
//            userHasCollect = collectService.count(userId, (byte)0, id);
//        }

        // 记录用户的足迹 异步处理
//        if (userId != null) {
//            executorService.execute(()->{
//                LitemallFootprint footprint = new LitemallFootprint();
//                footprint.setUserId(userId);
//                footprint.setGoodsId(id);
//                footprintService.add(footprint);
//            });
//        }
        FutureTask<List> goodsAttributeListTask = new FutureTask<>(goodsAttributeListCallable);
        FutureTask<Object> objectCallableTask = new FutureTask<>(objectCallable);
        FutureTask<List> productListCallableTask = new FutureTask<>(productListCallable);
        FutureTask<List> issueCallableTask = new FutureTask<>(issueCallable);
//        FutureTask<Map> commentsCallableTsk = new FutureTask<>(commentsCallable);
        FutureTask<LitemallBrand> brandCallableTask = new FutureTask<>(brandCallable);
//        FutureTask<List> grouponRulesCallableTask = new FutureTask<>(grouponRulesCallable);

        executorService.submit(goodsAttributeListTask);
        executorService.submit(objectCallableTask);
        executorService.submit(productListCallableTask);
        executorService.submit(issueCallableTask);
//        executorService.submit(commentsCallableTsk);
        executorService.submit(brandCallableTask);
//        executorService.submit(grouponRulesCallableTask);

        Map<String, Object> data = new HashMap<>();

        try {
            data.put("info", info);
            data.put("userHasCollect", userHasCollect);
            data.put("issue", issueCallableTask.get());
//            data.put("comment", commentsCallableTsk.get());
            data.put("specificationList", objectCallableTask.get());
            data.put("productList", productListCallableTask.get());
            data.put("attribute", goodsAttributeListTask.get());
            data.put("brand", brandCallableTask.get());
//            data.put("groupon", grouponRulesCallableTask.get());
            //SystemConfig.isAutoCreateShareImage()
            data.put("share", false);

        }
        catch (Exception e) {
            e.printStackTrace();
        }

        //商品分享图片地址
        if(info!=null){
            data.put("shareImage", info.getShareUrl());
        }

        return ResponseUtil.ok(data);
    }


    /**
     * 商品详情页面“大家都在看”推荐商品
     *
     * @param id, 商品ID
     * @return 商品详情页面推荐商品
     */
    @RequestMapping("/related")
    public Object related(@NotNull Integer id) {
        LitemallGoods goods = goodsService.findById(id);
        if (goods == null) {
            return ResponseUtil.badArgumentValue();
        }

        // 目前的商品推荐算法仅仅是推荐同类目的其他商品
        int cid = goods.getCategoryId();

        // 查找六个相关商品
        int related = 6;
        List<LitemallGoods> goodsList = goodsService.queryByCategory(cid, 0, related);
        return ResponseUtil.okList(goodsList);
    }
}
